package executor;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

public class DiyThreadPoolExecutor {

    //任务队列
    private BlockingDeque<Runnable> blockingDeque;
    //线程数量
    private AtomicInteger workerCount = new AtomicInteger();
    //核心线程数量
    private int corePoolSize;
    //最大线程数量
    private int maximumPoolSize;
    //拒绝策略
    private RejectedExecutionHandler rejectedExecutionHandler;

    public DiyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, BlockingDeque<Runnable> blockingDeque,RejectedExecutionHandler rejectedExecutionHandler) {
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.blockingDeque = blockingDeque;
        this.rejectedExecutionHandler = rejectedExecutionHandler;
    }

    public DiyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, BlockingDeque<Runnable> blockingDeque) {
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.blockingDeque = blockingDeque;
        this.rejectedExecutionHandler = new RejectedExecutionHandler(){
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

            }
        };
    }


    public class Worker extends Thread {
        Runnable firstTask;
        public Worker(Runnable firstTask) {
            this.firstTask = firstTask;
        }
        @Override
        public void run() {
            try {
                while (true) {
                    Runnable runnable = firstTask;
                    if (runnable != null || (runnable = blockingDeque.take()) != null) {
                        runnable.run();
                        runnable=null;
                    }
                }
            } catch (Exception e) {
            }
        }
    }

    public void execute(Runnable command) {
        //1 判断核心线程数量
        if (workerCount.get() < corePoolSize) {
            if (workerCount.incrementAndGet() < corePoolSize) {
                new Worker(command).run();
                return;
            } else {
                workerCount.decrementAndGet();
            }
        }

        //2 向阻塞队列添加数据，判断队列是否满了
        if(blockingDeque.offer(command)){
            return;
        }
        //3 判断最大线程数量
        if (workerCount.get() < maximumPoolSize) {
            if (workerCount.incrementAndGet() < maximumPoolSize) {
                new Worker(command).run();
                return;
            } else {
                workerCount.decrementAndGet();
            }
        }
        //4 拒绝策略
        rejectedExecutionHandler.rejectedExecution(command,null);
    }

}
